#include "TokenBlock.h"
#include "TokenSen.h"
#include "Token.h"
#include "Error.h"
#include <string>
#include <cassert>
#include <iostream> // for clog
using namespace std;
void TokenBlock::run(bool enabled /*= true*/)
{
	Context* ctx = Context::getInstance();
	//analyse the first line to determine the indent level
	string line;
	int ind;
	do
	{
		line = ctx -> nextLine();
		ind = 0;
		while (ind < line.size() &&
			(line[ind] == ' ' || line[ind] == '\t')
			) ind ++;
	} while (ind >= line.size());
	string indentFather = ctx -> indent.back();
	if (ind <= indentFather.size())
		throw Error("More indent expected but not found.");
	if (indentFather != line.substr(0,indentFather.size()))
		throw Error("Mix tab and space.");
	if (ctx -> indent.back() == "" && ind != 1)
		throw Error("Unexpected indent.");
	//clog << "()()" << ind << endl;
	string indentNew = line.substr(0, ind);
	ctx -> indent.push_back(indentNew);
	//clog << "BLOCK START" << endl;
	try
	{
		//process each line
		do
		{
			TokenSen ts(line.substr(ind, line.size()-ind));
			//clog << "---" << line.substr(ind, line.size()-ind) << endl;
			ts.run(enabled);
			line = ctx -> nextLine();
			ind = 0;
			while (ind < line.size() &&
				(line[ind] == ' ' || line[ind] == '\t')
				) ind ++;
			//clog << "()()" << ind << endl;
		}
		while (ind == indentNew.size() && line.substr(0, ind) == indentNew);
		//the last read line has less indent, so this block ends
		//assert(ind == indentFather.size()); // the assertion is wrong, ind is one of its ancestor rather than its father
		if (ind == indentNew.size()) // so line.substr(0, ind) != indentNew
			throw Error("Mix tab and space.");
		else if (ind > indentNew.size())
			throw Error("Unexpected indent.");
		ctx -> rollbackLine();
	}
	catch (ErrorBreak& e)
	{
		ctx -> indent.pop_back();
		throw e;
	}
	catch (ErrorExit& e)
	{
		ctx -> indent.pop_back();
		throw e;
	}
	catch (Error& e)
	{
		ctx -> indent.pop_back();
		//clog << "BLOCK END" << endl;
		throw e;
	}
	//clog << "BLOCK END" << endl;
	ctx -> indent.pop_back();
}

